package serveur;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;

public class ServeurManager {
	 
	private int port;
	private String ip;
	private Socket socket;
	private DataInputStream in;
	private DataOutputStream out;
	private static String nomEquipe = "CopyPaste";
	private Initialisation init;
	private boolean pretAJouer=false;
	private Coup coup;
	private boolean gagne=false;
	private boolean perdu=false;
	
	private int tour = 0;
	
	public ServeurManager(Integer port, String ip){
		try {
			this.socket = new Socket(ip,port);
			this.in = new DataInputStream(socket.getInputStream());
			this.out = new DataOutputStream(socket.getOutputStream());
			this.initialisation();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public boolean getGagne(){
		return this.gagne;
	}
	
	public boolean getPerdu(){
		return this.perdu;
	}
	public Coup getCoup(){
		return this.coup;
	}
	public boolean getPretAJouer(){
		return this.pretAJouer;
	}
	public void initialisation(){
		try {
			Flux.ecriture(this.out,nomEquipe);
			try {
				this.reponseInitialisation();
			} catch (ServeurException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public void reponseInitialisation() throws ServeurException{
		boolean reponseRecu = false;
		String reponse;
		while( !reponseRecu ){
			try {
				reponse = Flux.lecture(this.in);
				if (reponse.length()>0){
					//le serveur a repondu
					reponseRecu=true;
					this.analyseReponseInitialisation(reponse);
					reponse="";
				}			
			} catch (IOException e) {
				throw new ServeurException("Probleme de lecteur a travers la socket lors de l'initialisation", e);
			}
		}
	}
	
	public void analyseReponseInitialisation(String reponseInit) throws ServeurException {
		String[] reponse = reponseInit.split(":");
		if (reponse[1].equals("1")){
			this.init = new Initialisation(1);
			this.lectureCoup();
		}
		else if (reponse[1].equals("0")){
			this.init = new Initialisation(0);
			this.lectureCoup();
		}
		else {
			throw new ServeurException("Reponse demande de connexion = " + reponse[1]);
		}
	}

	public Initialisation getInit() {
		return init;
	}
	
	public void lectureCoup() throws ServeurException{
		boolean lectureCoup = false;
		String reponse;
		while (!lectureCoup){
			try {
				reponse = Flux.lecture(this.in);
				if (reponse.length()>0){
					lectureCoup = true;
					try {
						this.decrypteCoup(reponse);
						reponse = "";
					} catch (ServeurException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				throw new ServeurException("Probleme de lecture a travers la socket lors de l'initialisation", e);
			}
		}
	}
	
	public void decrypteCoup(String reponseCoup) throws ServeurException {
		String[] coup = reponseCoup.split(";")[0].split(":");
		if (coup[0].equals("m")){ //Mouvement
			if(this.verifMouvementValide(coup[1])){
				this.coup = new Mouvement(coup[1]);
				this.joueCoup();
			}
			else {
				throw new ServeurException("Coup indefini : " + coup[1] );
			}
		}
		else if (coup[0].equals("b")){//barriere
			String[] coor = coup[1].split(",");
			int x = Integer.parseInt(coor[0]);
			int y = Integer.parseInt(coor[1]);
			String emplacement = coup[2];
			if (this.verifPlacementBariere(x, y, emplacement)){
				this.coup = new Barriere(emplacement, x, y);
			}
			this.joueCoup();
		}
		else if(coup[0].equals("init")) {
			this.pretAJouer=true;
			this.joueCoup();
		}
		else if (coup[0].equals("win")){
			this.gagne=true;
		}else if (coup[0].equals("loose")){
			this.perdu=true;
		}
		else {
			throw new ServeurException("Probleme lors de la lecture du coup joue par l'adversaire");
		}
	}
	
	public boolean verifPlacementBariere(int x, int y, String emplacement){
		return (x >= 0 && x <= 16 && y >= 0 && y <= 16 && (emplacement.equals("V") || emplacement.equals("H")));
	}
	
	public boolean verifMouvementValide(String mouvement){
		return (mouvement.equals("N") || mouvement.equals("E") || mouvement.equals("S") || mouvement.equals("W") 
				|| mouvement.equals("NN") || mouvement.equals("NE") || mouvement.equals("NW")
				|| mouvement.equals("SS") || mouvement.equals("SE") || mouvement.equals("SW") || mouvement.equals("EE") || mouvement.equals("WW"));
	}
	
	
	public void deplacerPion(String orientation) throws ServeurException{
		if (this.verifMouvementValide(orientation)){
			try {
				Flux.ecriture(this.out,"m:"+orientation);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				throw new ServeurException("Probleme pdt ecriture Socket pr deplacer un pion",e);
			}
		}
		else {
			throw new ServeurException("Probleme lors de la demande de deplacement : orientation invalide : "+orientation);
		}
	}
	
	public void ajouterBariere(int x,int y,String orientation) throws ServeurException{
		if (this.verifPlacementBariere(x,y,orientation)){
			try {
				Flux.ecriture(this.out,"b:"+x+","+y+":"+orientation);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				throw new ServeurException("Probleme pdt ecriture Socket pr ajouter une bariere",e);
			}
		}
		else {
			throw new ServeurException("Probleme lors de la demande d'ajout de bariere : orientation invalide : x= "+x+"y= "+y+"orientation = "+orientation);
		}
	}
	
	public void joueCoup(){
		if(this.tour == 0){
			try {
				this.ajouterBariere(3, 5,"H");
			} catch (ServeurException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		else if(this.tour % 2 == 0){
			try {
				this.deplacerPion("E");
			} catch (ServeurException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		else {
			try {
				this.deplacerPion("W");
			} catch (ServeurException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		this.tour ++;
	}
	public static void main(String args[]){
		ServeurManager s =new ServeurManager(new Integer(args[2]),args[1]);
		
		
	}
}
